#include "tongxunlu.h"
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
void readFile(Contact contacts[], int *count) // 读文件函数，用于从文件中读取联系人信息
{
    FILE* fp = fopen("data.dat", "rb"); // 以二进制读取模式打开文件 data.dat
    if(fp == NULL) // 如果文件打开失败
    {
        printf("未找到文件"); // 提示用户未找到文件
        return; // 结束函数
    }
    int i = 0; // 初始化人数计数器
    while(1) // 无限循环，直到文件结束
    {
        Contact people; // 定义一个 Contact 类型变量用于存储读取的数据
        int n = fread(&people, sizeof(Contact), 1, fp); // 从文件中读取一个 Contact 类型的数据到 people 变量中
        if(n == 0) // 如果读取的字节数为0，表示文件结束
            break; // 退出循环
        contacts[i] = people; // 将读取的联系人信息存入 contacts 数组中
        (*count)++; // 联系人数量加1
        i++; // 人数计数器加1
    }
    fclose(fp); // 关闭文件
    return; // 返回函数
}

void writeFile(Contact contacts[], int count) // 写文件函数，用于将联系人信息写入文件
{
    FILE* fp = fopen("data.dat", "wb"); // 以二进制写入模式打开文件 data.dat
    if(fp == NULL) // 如果文件打开失败
    {
        printf("未找到文件"); // 提示用户未找到文件
        return; // 结束函数
    }
    Contact people; // 定义一个 Contact 类型变量用于存储要写入的数据
    for(int i = 0; i < count; i++) // 遍历联系人数组
    {
        people = contacts[i]; // 将联系人信息复制到 people 变量中
        fwrite(&people, sizeof(Contact), 1, fp); // 将 people 变量的数据写入文件
    }
    fclose(fp); // 关闭文件
    return; // 返回函数
}

// 添加联系人
void AddContact(Contact contacts[], int *count, int n) { // 添加联系人函数，用于向联系人群组中添加新联系人

    for(int i = 0; i < n; i++) // 循环 n 次，为每个新联系人输入信息
    {
        printf("请输入姓名："); 
        scanf("%s", contacts[(*count)+i].name); // 读取用户输入的姓名并存储到联系人的 name 字段
        printf("请输入职务："); 
        scanf("%s", contacts[(*count)+i].position); // 读取用户输入的职务并存储到联系人的 position 字段
        printf("请输入职称："); 
        scanf("%s", contacts[(*count)+i].title); // 读取用户输入的职称并存储到联系人的 title 字段
        printf("请输入手机："); 
        scanf("%s", contacts[(*count)+i].phone); // 读取用户输入的手机号码并存储到联系人的 phone 字段
        printf("请输入Email："); 
        scanf("%s", contacts[(*count)+i].email); // 读取用户输入的电子邮箱并存储到联系人的 email 字段
    }
    (*count) = (*count) + n; // 将联系人数量增加 n
    printf("联系人添加成功。\n"); // 提示用户联系人添加成功
}

// 删除联系人
void DeleteContact(Contact contacts[], int *count) { // 删除联系人函数，用于从联系人群组中删除指定姓名的人

    char name[20]; // 定义一个字符数组用于存储要删除的联系人姓名
    printf("请输入要删除的联系人姓名："); 
    scanf("%s", name); 
    int found = 0; // 定义一个标志变量，用于标记是否找到要删除的联系人
    for (int i = 0; i < *count; i++) { // 遍历联系人数组
        if (strcmp(contacts[i].name, name) == 0) { // 检查当前联系人是否与要删除的联系人姓名相同
            found = 1; // 设置标志变量为1，表示找到要删除的联系人
            for (int j = i; j < *count - 1; j++) { // 将联系人数组中当前联系人之后的元素向前移动一位
                contacts[j] = contacts[j + 1];
            }
            (*count)--; // 联系人数量减1
            printf("联系人删除成功。\n");
            break; // 结束循环
        }
    }
    if (!found) { // 如果标志变量为0，表示未找到要删除的联系人
        printf("未找到该联系人。\n"); // 提示用户未找到该联系人
    }
}

// 修改联系人信息
void ModifyContact(Contact contacts[], int count) { // 修改联系人函数，用于修改联系人群组中指定姓名的联系人信息

    char name[20]; // 定义一个字符数组用于存储要修改的联系人姓名
    printf("请输入要修改的联系人姓名："); 
    scanf("%s", name); // 读取用户输入的姓名
    int found = 0; // 定义一个标志变量，用于标记是否找到要修改的联系人
    for (int i = 0; i < count; i++) { // 遍历联系人数组
        if (strcmp(contacts[i].name, name) == 0) { // 检查当前联系人是否与要修改的联系人姓名相同
            found = 1; // 设置标志变量为1，表示找到要修改的联系人
            printf("请输入新的职务："); 
            scanf("%s", contacts[i].position); // 读取用户输入的新的职务并存储到联系人的 position 字段
            printf("请输入新的职称："); 
            scanf("%s", contacts[i].title); // 读取用户输入的新的职称并存储到联系人的 title 字段
            printf("请输入新的手机："); 
            scanf("%s", contacts[i].phone); // 读取用户输入的新手机号码并存储到联系人的 phone 字段
            printf("请输入新的Email："); 
            scanf("%s", contacts[i].email); // 读取用户输入的新电子邮箱并存储到联系人的 email 字段
            printf("联系人信息修改成功。\n"); 
            break; // 结束循环
        }
    }
    if (!found) { // 如果标志变量为0，表示未找到要修改的联系人
        printf("未找到该联系人。\n"); // 提示用户未找到该联系人
    }
}

// 显示所有联系人信息
void DisplayContacts(const Contact contacts[], int count) { // 显示联系人函数，用于打印联系人群组中的所有联系人信息

    printf("姓名\t职务\t职称\t    手机\tEmail\n"); // 打印表头，分隔符为制表符
    for (int i = 0; i < count; i++) { // 遍历联系人数组
        PrintContact(&contacts[i]); // 调用 PrintContact 函数打印单个联系人的信息
    }
}


// 打印联系人信息
void PrintContact(const Contact *contact) { // PrintContact 函数用于打印单个联系人的信息

    if (contact) { // 检查传递的联系人指针是否不为空
        printf("%s\t%s\t%s\t%s\t%s\n", // 使用格式化字符串打印联系人信息，使用制表符分隔
               contact->name, // 打印联系人姓名
               contact->position, // 打印联系人职务
               contact->title, // 打印联系人职称
               contact->phone, // 打印联系人手机号码
               contact->email); // 打印联系人电子邮箱
    }
}


// 搜索联系人
void SearchContacts(const Contact contacts[], int count) { // SearchContacts 函数用于搜索联系人群组中符合特定属性和关键字的联系人

    char searchKey[20]; // 定义一个字符数组用于存储搜索关键字
    int attribute; // 定义一个整数变量用于存储要搜索的联系人属性
    printf("请输入要搜索的联系人属性（1: 姓名， 2: 职务， 3: 职称， 4: 手机， 5: Email）和对应的值："); // 提示用户输入要搜索的联系人属性及其值
    scanf("%d", &attribute); // 读取用户输入的属性值
    getchar(); // 清除输入流中的换行符
    printf("请输入搜索的关键字："); // 提示用户输入搜索关键字
    scanf("%s", searchKey); // 读取用户输入的关键字

    int found = 0; // 定义一个标志变量，用于标记是否找到符合搜索条件的联系人
    for (int i = 0; i < count; i++) { // 遍历联系人数组
        switch (attribute) { // 根据用户输入的属性进行分支处理
            case 1: // 如果是搜索姓名
                if (strstr(contacts[i].name, searchKey) != NULL) { // 使用 strstr 函数检查姓名中是否包含搜索关键字
                    PrintContact(&contacts[i]); // 打印找到的联系人信息
                    found = 1; // 设置标志变量为1，表示找到符合条件的人
                }
                break;
            case 2: // 如果是搜索职务
                if (strstr(contacts[i].position, searchKey) != NULL) { // 使用 strstr 函数检查职务中是否包含搜索关键字
                    PrintContact(&contacts[i]); // 打印找到的联系人信息
                    found = 1; // 设置标志变量为1，表示找到符合条件的人
                }
                break;
            case 3: // 如果是搜索职称
                if (strstr(contacts[i].title, searchKey) != NULL) { // 使用 strstr 函数检查职称中是否包含搜索关键字
                    PrintContact(&contacts[i]); // 打印找到的联系人信息
                    found = 1; // 设置标志变量为1，表示找到符合条件的人
                }
                break;
            case 4: // 如果是搜索手机
                if (strstr(contacts[i].phone, searchKey) != NULL) { // 使用 strstr 函数检查手机中是否包含搜索关键字
                    PrintContact(&contacts[i]); // 打印找到的联系人信息
                    found = 1; // 设置标志变量为1，表示找到符合条件的人
                }
                break;
            case 5: // 如果是搜索 Email
                if (strstr(contacts[i].email, searchKey) != NULL) { // 使用 strstr 函数检查 Email 中是否包含搜索关键字
                    PrintContact(&contacts[i]); // 打印找到的联系人信息
                    found = 1; // 设置标志变量为1，表示找到符合条件的人
                }
                break;
            default: // 如果输入的属性值无效
                printf("无效的属性。\n"); // 提示用户输入了无效的属性
                return; // 结束函数执行
        }
    }
    if (!found) { // 如果标志变量为0，表示未找到符合搜索条件的联系人
        printf("未找到相关联系人。\n"); // 提示用户未找到相关联系人
    }
}

// 排序
void SortContacts(Contact contacts[], int count) { // SortContacts 函数用于对联系人群组按姓名进行升序排序

    Contact temp; // 定义一个 Contact 类型的临时变量，用于交换数据
    for (int i = 0; i < count - 1; i++) { // 外层循环遍历数组直到倒数第二个元素
        for (int j = i + 1; j < count; j++) { // 内层循环遍历数组从 i+1 到最后一个元素
            if (strcmp(contacts[i].name, contacts[j].name) > 0) { // 使用 strcmp 函数比较两个联系人的姓名
                temp = contacts[i]; // 如果 contacts[i] 的姓名大于 contacts[j] 的姓名，交换两者数据
                contacts[i] = contacts[j];
                contacts[j] = temp;
            }
        }
    }
}
